import { Injectable, NotFoundException } from '@nestjs/common';
import { RegisterDto, LoginDto, ForgotDto } from './dto/login.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from '../user/entity/user.entity';
import { RedisService } from '../redis/redis.service';
import * as bcrypt from 'bcrypt';

@Injectable()
export class LoginService {
  constructor(
    // 注入 User 实体的 Repository
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
    // 注入 RedisService
    private readonly redisService: RedisService,
  ) { }

  /**
   * ? 用户登录
   */
  async login(body: LoginDto) {
    console.log(body);
    try {
      // 检查邮箱是否存在
      const user = await this.userRepository.findOne({
        where: { email: body.email },
        select: ['id', 'email', 'password'], // 仅查询需要的字段
      });
      if (!user) {
        throw new NotFoundException(`邮箱 ${body.email} 不存在, 请先注册`);
      }
      // 验证密码
      const isPasswordValid = await bcrypt.compare(body.password, user.password);
      if (!isPasswordValid) {
        throw new NotFoundException('密码错误');
      }
      return {
        code: 200,
        data: {
          id: user.id
        },
        message: 'Login success',
      }
    } catch (error) {
      throw new NotFoundException(error.message);
    }
  }

  /**
   * ? 用户注册
   */
  async register(body: RegisterDto, userIp: string) {
    console.log(body);
    try {
      // 检查邮箱是否已存在
      const existingEmail = await this.userRepository.findOneBy({ email: body.email });
      if (existingEmail) {
        throw new NotFoundException(`邮箱 ${body.email} 已存在`);
      }
      // 验证验证码
      const redisCode = await this.redisService.getCode(`register:${body.email}`);
      if (!redisCode) {
        throw new NotFoundException('验证码过期');
      }
      if (body.code !== redisCode) {
        throw new NotFoundException('验证码错误');
      }
      // 密码加密（DTO 是明文，实体存密文）
      const salt = await bcrypt.genSalt(10);
      const hashedPassword = await bcrypt.hash(body.password, salt);
      // 创建用户实体
      const user = this.userRepository.create({
        ...body,
        register_ip: userIp, // 存储用户注册时的IP地址
        password: hashedPassword, // 替换为加密后的密码
      });
      // 将用户实体保存到数据库
      const savedUser = await this.userRepository.save(user);
      if (!savedUser) {
        throw new NotFoundException('注册失败');
      }
      return {
        code: 200,
        message: 'Register success',
      }
    } catch (error) {
      throw new NotFoundException(error.message);
    }
  }

  /**
   * ? 忘记密码
   */
  async forgot(body: ForgotDto) {
    console.log(body);
    try {
      // 检查邮箱是否存在
      const user = await this.userRepository.findOne({
        where: { email: body.email },
        select: ['id', 'email', 'password'], // 仅查询需要的字段
      });
      if (!user) {
        throw new NotFoundException(`邮箱 ${body.email} 不存在, 请先注册`);
      }
      // 验证验证码
      const redisCode = await this.redisService.getCode(`forgot:${body.email}`);
      if (!redisCode) {
        throw new NotFoundException('验证码过期');
      }
      if (body.code !== redisCode) {
        throw new NotFoundException('验证码错误');
      }
      // 密码加密（DTO 是明文，实体存密文）
      const salt = await bcrypt.genSalt(10);
      const hashedPassword = await bcrypt.hash(body.password, salt);
      // 更新用户密码
      await this.userRepository.update(user.id, {
        password: hashedPassword, // 替换为加密后的密码
      });
      return {
        code: 200,
        message: 'Password reset success',
      }
    } catch (error) {
      throw new NotFoundException(error.message);
    }
  }

  // 1. 创建用户（入库）
  async create(createUserDto: RegisterDto): Promise<User> {
    // 密码加密（DTO 是明文，实体存密文）
    // const salt = await bcrypt.genSalt();
    // const hashedPassword = await bcrypt.hash(createUserDto.password, salt);

    // 创建实体实例并赋值
    const user = this.userRepository.create({
      ...createUserDto,
      // password: hashedPassword, // 替换为加密后的密码
    });

    // 保存到数据库
    return this.userRepository.save(user);
  }

  // 2. 查询所有用户
  async findAll(): Promise<User[]> {
    return this.userRepository.find(); // SELECT * FROM users
  }

  // 3. 根据 ID 查询用户
  async findOne(id: number): Promise<User> {
    const user = await this.userRepository.findOneBy({ id });
    if (!user) {
      throw new NotFoundException(`用户 ID ${id} 不存在`);
    }
    return user;
  }

  // 4. 更新用户
  async update(id: number, updateUserDto: RegisterDto): Promise<User> {
    // 先检查用户是否存在
    await this.findOne(id);

    // 更新数据（部分更新）
    await this.userRepository.update(id, updateUserDto);

    // 返回更新后的用户
    return this.findOne(id);
  }

  // 5. 删除用户
  async remove(id: number): Promise<void> {
    // 先检查用户是否存在
    await this.findOne(id);

    await this.userRepository.delete(id);
  }
}
